package com.jeespring.business.service.impl;

import com.jeespring.dto.BusinessDTO;
import com.jeespring.dto.ResponseDTO;
import com.jeespring.entity.Order;
import com.jeespring.entity.Storage;
import com.jeespring.enums.RspStatusEnum;
import com.jeespring.exception.DefaultException;
import com.jeespring.service.BusinessService;
import com.jeespring.service.OrderService;
import com.jeespring.service.StorageService;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

/**
 * @Title: BusinessServiceImpl
 * @Description:
 * @Author 张朝阳
 * @Date 2020/11/29 16:08
 */
@Service
@Slf4j
public class BusinessServiceImpl implements BusinessService {

    @Reference
    private StorageService storageService;

    @Reference
    private OrderService orderService;

    /**
     * 处理业务逻辑 正常的业务逻辑
     * @Param:
     * @Return:
     */
    @GlobalTransactional(timeoutMills = 300000,name = "jeespring-business-seata")
    @Override
    public ResponseDTO submitOrder(BusinessDTO businessDTO) {
        log.info("开始全局事务，XID = " + RootContext.getXID());
        ResponseDTO<Object> response = new ResponseDTO<>();
        //1、扣减库存
        Storage storage = new Storage();
        storage.setCommodityCode(businessDTO.getCommodityCode());
        storage.setCommodityName(businessDTO.getCommodityName());
        storage.setCount(businessDTO.getCount());
        ResponseDTO storageResponse = storageService.decrStorage(storage);

        // 异常发生
        if (businessDTO.getFlag() == 1){
            int i = 10/0;
        }

        //2、创建订单
        BusinessDTO business = new BusinessDTO();
        business.setUserId(businessDTO.getUserId());
        business.setCommodityCode(businessDTO.getCommodityCode());
        business.setCount(businessDTO.getCount());
        long amount = businessDTO.getMoney() * businessDTO.getCount();
        business.setAmount(amount);
        business.setFlag(businessDTO.getFlag());
        ResponseDTO<Order> orderResponse = orderService.createOrder(business);

        if (!storageResponse.isSuccess() || !orderResponse.isSuccess()) {
            throw new DefaultException(RspStatusEnum.FAIL);
        }

        // 异常发生
        if (businessDTO.getFlag() == 3){
            int i = 10/0;
        }

        response.setSuccess(true);
        response.setMessage("提交订单成功！");
        response.setData(response.getData());
        return response;
    }

    /**
     * 出处理业务服务，出现异常回顾
     *
     * @param businessDTO
     * @return
     */
    @GlobalTransactional(timeoutMills = 300000, name = "dubbo-gts-seata-example")
    @Override
    public ResponseDTO submitOrderException(BusinessDTO businessDTO) {
        log.info("开始全局事务，XID = " + RootContext.getXID());
        ResponseDTO<Object> response = new ResponseDTO<>();
        //1、扣减库存
        Storage storage = new Storage();
        storage.setCommodityCode(businessDTO.getCommodityCode());
        storage.setCommodityName(businessDTO.getCommodityName());
        storage.setCount(businessDTO.getCount());
        ResponseDTO storageResponse = storageService.decrStorage(storage);

        //2、创建订单
        BusinessDTO business = new BusinessDTO();
        business.setUserId(businessDTO.getUserId());
        business.setCommodityCode(businessDTO.getCommodityCode());
        business.setCount(businessDTO.getCount());
        long amount = businessDTO.getMoney() * businessDTO.getCount();
        business.setAmount(amount);
        ResponseDTO<Order> orderResponse = orderService.createOrder(business);

//        打开注释测试事务发生异常后，全局回滚功能
        if (businessDTO.getFlag() == 1) {
            throw new RuntimeException("测试抛异常后，分布式事务回滚！");
        }

        if (!storageResponse.isSuccess() || !orderResponse.isSuccess()) {
            throw new DefaultException(RspStatusEnum.FAIL);
        }

        response.setSuccess(true);
        response.setMessage("提交订单成功！");
        response.setData(response.getData());
        return response;
    }
}
